package com.crois.barrier.web.plugin.post;


import com.crois.barrier.common.enums.PluginEnum;
import com.crois.barrier.common.enums.PluginTypeEnum;
import com.crois.barrier.common.exception.BarrierExceptionEnum;
import com.crois.barrier.plugin.BarrierPlugin;
import com.crois.barrier.plugin.BarrierPluginChain;
import com.crois.barrier.web.resp.BarrierResponseUtils;
import com.crois.barrier.web.support.ServerWebExchangeUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Objects;

/**
 * @author Hou Ze Yu
 * @description webclient 响应处理插件
 * @date 2020/7/13
 */
public class WebClientResponsePlugin implements BarrierPlugin {

    @Override
    public Mono<Void> execute(ServerWebExchange exchange, BarrierPluginChain chain) {
        return chain.execute(exchange).then(Mono.defer(() -> {

                ServerHttpResponse response = exchange.getResponse();
                ClientResponse clientResponse = exchange.getAttribute(ServerWebExchangeUtils.BARRIER_CLIENT_RESPONSE_ATTR);
                if ((Objects.isNull(clientResponse)
                        ||response.getStatusCode()== HttpStatus.BAD_GATEWAY
                        ||response.getStatusCode()==HttpStatus.INTERNAL_SERVER_ERROR)){
                    return BarrierResponseUtils.error(exchange, BarrierExceptionEnum.BARRIER_GATEWAY_SERVICE_RESULT_ERROR);
                }else if (response.getStatusCode()==HttpStatus.GATEWAY_TIMEOUT){
                    return BarrierResponseUtils.error(exchange,BarrierExceptionEnum.BARRIER_GATEWAY_SERVICE_TIMEOUT);
                }
                response.getCookies().putAll(clientResponse.cookies());
                response.getHeaders().putAll(clientResponse.headers().asHttpHeaders());
                response.setStatusCode(clientResponse.statusCode());
                return response.writeWith(clientResponse.body(BodyExtractors.toDataBuffers()));
        }));
    }

    @Override
    public PluginTypeEnum pluginType() {
        return PluginTypeEnum.POST;
    }

    @Override
    public String name() {
        return PluginEnum.WEB_CLIENT_RESPONSE.getName();
    }

    @Override
    public int order() {
        return PluginEnum.WEB_CLIENT_RESPONSE.getCode();
    }

    @Override
    public Boolean skip(ServerWebExchange exchange) {
        return false;
    }
}
